import json
import logging
import math
from datetime import date, datetime, timedelta
from decimal import Decimal
import pprint
from typing import Literal

from auditlog.context import set_actor
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import CharField, F, Q, Value
from django.db.models.functions import Concat
from django.shortcuts import get_object_or_404
from django.utils import timezone
from ninja import File, Form, ModelSchema, Router, Schema
from ninja.files import UploadedFile
from ninja.orm import create_schema

import db
from customauth.models import MyUser
from decorators.auth_login import login_for_logs_by_mpp
from naryad import xlsx_gen
from naryad.models import (
    Buhreport,
    Comments,
    Container,
    Etaps,
    Images,
    It_lab,
    Mpp_podr,
    Patient,
    Pl_uslp,
    Sdl_set,
    Spr_access,
    Spr_lpu,
    Spr_opl,
    Spr_sdl,
    User_sdl,
)
from naryad.views import create_buh_report, naryad_close_by_doc, naryad_close_by_st_custom_date, naryad_move
from periods.models import Periods
from tarifs.models import Uslugi

router = Router(tags=["lab"])


class Error(Schema):
    message: str


class Message(Schema):
    message: str


class StatusMessage(Schema):
    ok: bool
    status: int
    message: str


@router.get("/hello")
def hello(request) -> Literal["Hello world"]:  # noqa: ARG001
    return "Hello world"


class PatientSchema(ModelSchema):
    class Meta:
        model = Patient
        fields = "__all__"


class UslSchema(Schema):
    idkv: str
    kusl: str
    usl: int
    nusl: str
    kol: int
    uet: float
    price: float
    stu: float


@router.get(
    "/patients_all/",
    response={200: list[PatientSchema], 403: Error(message="Ошибка обработки запроса")},
)
def list_patients(request) -> list[PatientSchema]:  # noqa: ARG001
    return list(Patient.objects.order_by("uid").distinct("uid"))


@router.get(
    "/patients_by_fam/",
    response={200: list[PatientSchema], 403: Error(message="Ошибка обработки запроса")},
)
def patients_by_fam(request, fam: str) -> list[PatientSchema]:  # noqa: ARG001
    return list(
        Patient.objects.filter(fam__startswith=fam).order_by("uid").distinct("uid"),
    )


@router.get(
    "/patient_by_uid/{patient_uid}",
    response={
        200: PatientSchema | None,
        403: Error(message="Ошибка обработки запроса"),
    },
)
def patient_by_uid(request, patient_uid: int) -> PatientSchema | None:  # noqa: ARG001
    pat = (
        Patient.objects.filter(uid=patient_uid).order_by("uid").distinct("uid").first()
    )
    if pat is None:
        return None
    return pat


@router.get(
    "/add_usl/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
# # @login_for_logs_by_mpp
def add_usl(request, naryad_nkv: str, kusl: str, kol: int):  # noqa: ANN201, ARG001
    naryad = It_lab.objects.get(nkv=naryad_nkv)
    usluga = Uslugi.objects.filter(kusl=kusl).first()
    if Pl_uslp.objects.filter(naryad=naryad, kusl=kusl).exists():
        new_usl = Pl_uslp.objects.get(naryad=naryad, kusl=kusl)
        new_usl.kol += kol
        new_usl.save()
    else:
        Pl_uslp.objects.create(
            idkv=naryad.idkv,
            naryad=naryad,
            kusl=kusl,
            usl=usluga.usl,
            kol=kol,
            uet=usluga.uet * kol,
            price=usluga.trf,
            nusl=usluga.nusl,
        )
    return 200, {"ok": True, "status": 200, "message": "add usl completed"}


@router.get(
    "/delete_usl/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
# # @login_for_logs_by_mpp
def delete_usl(request, usluga_id):  # noqa: ANN201, ARG001
    Pl_uslp.objects.get(id=usluga_id).delete()
    return 200, {"ok": True, "status": 200, "message": "add usl completed"}


class PlUslpSchema(Schema):
    id: int
    kusl: str
    nusl: str
    kol: int
    uet: Decimal
    price: Decimal
    stu: Decimal


@router.get(
    "/uslugi_by_nkv/",
    response={200: list[PlUslpSchema], 403: Error(message="Ошибка обработки запроса")},
)
def uslugi_by_nkv(request, naryad_nkv: str):  # noqa: ANN201, ARG001
    return Pl_uslp.objects.filter(naryad__nkv=naryad_nkv)


class UslugiSchema(Schema):
    usl: int
    kusl: str
    ok_isl_p: str
    nusl: str
    uet: float
    trf: float
    name: str = None


@router.get(
    "/uslugi_map/",
    response={200: list[UslugiSchema], 403: Error(message="Ошибка обработки запроса")},
)
def uslugi_map(request) -> list[UslugiSchema]:  # noqa: ARG001
    usl_dict = {}
    usls = Uslugi.objects.filter(isp=1)
    for usl in usls:
        usl_dict[usl.kusl] = usl
    return usl_dict


@router.get(
    "/uslugi_all/",
    response={200: list[UslugiSchema], 403: Error(message="Ошибка обработки запроса")},
)
def uslugi_all(request) -> list[UslugiSchema]:  # noqa: ARG001
    return (
        Uslugi.objects.filter(isp=1)
        .annotate(name=Concat("kusl", Value(" - "), "nusl", output_field=CharField()))
        .values("usl", "kusl", "ok_isl_p", "nusl", "uet", "trf", "name")
    )  # type: ignore  # noqa: PGH003


@router.get(
    "/image_list/",
    response={200: list[str], 403: Error(message="Ошибка обработки запроса")},
)
def image_list(
    request,  # noqa: ARG001
    naryad_id: int = 0,
    naryad_nkv: str = "",
) -> list[str] | None:
    if naryad_nkv and naryad_id == 0:
        naryad = It_lab.objects.filter(nkv=naryad_nkv).first()
        if naryad is not None:
            naryad_id = naryad.id
    return [
        x.img.url
        for x in Images.objects.filter(etap__id=naryad_id).all().order_by("-id")
        if x.img
    ]


class UserSchema(Schema):
    login: str
    mpp: int
    fam: str
    im: str
    ot: str
    is_active: bool
    is_admin: bool


class LpuSchema(Schema):
    lpu: int
    name_lpu: str
    adress: str


class SdlSchema(Schema):
    sdl: int
    name_sdl: str


class SprAccessSchema(Schema):
    access: str
    access_name: str


class UserSdlSchema(Schema):
    user: UserSchema
    sdls: list[SdlSchema]
    access: list[SprAccessSchema]
    lpu: LpuSchema | None


ContainerSchema = create_schema(Container, depth=1)


class SprOplSchema(Schema):
    opl: int
    name_opl: str


class SdlSetSchema(Schema):
    doc: int
    tech: int
    lit: int
    pol: int
    cadcam: int
    gips: int
    tech_st: int


class NaryadSchema(Schema):
    id: int
    lpu: LpuSchema
    patient: PatientSchema
    idkv: str
    nkv: str
    dou: date
    dzr: date | None
    pdzr: date | None
    check_zav: bool
    check_tech: bool
    status: int
    stu: Decimal
    opl: SprOplSchema
    id_etap: int
    dn_etap: datetime
    dz_etap: datetime | None
    user_etap_link: UserSchema | None
    user_etap: str
    naryad_doc: UserSdlSchema
    mpp_etap: int | None
    sdl_etap: SdlSchema
    sdl_set: SdlSetSchema
    container: ContainerSchema | None
    image_count: int


@router.get(
    "/nar_list/",
    response={200: list[NaryadSchema], 403: Error(message="Ошибка обработки запроса")},
)
def nar_list(
    request,  # noqa: ARG001
    mpp: int,
    status: str = "close",
) -> list[NaryadSchema]:
    if status == "open":
        return list(
            It_lab.objects.filter(
                user_etap_link__mpp=mpp,
                dzr__isnull=True,
                pdzr__isnull=True,
                dz_etap__isnull=True,
                laboratory=True,
            ).select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            ),
        )

    if status == "close":
        today = date.today()
        last_year = today - timedelta(days=365)
        logging.warning(last_year, today)
        return list(
            It_lab.objects.filter(
                dzr__isnull=False,
                dzr__range=(last_year, today),
                mpp_etap=mpp,
                laboratory=True,
            ).select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            ),
        )
    if status == "st":
        return list(
            It_lab.objects.filter(
                id_etap=1,
                laboratory=True,
                dzr__isnull=True,
                pdzr__isnull=True,
            ).select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            ),
        )
    if status == "st_change_brigade":
        return list(
            It_lab.objects.filter(
                id_etap__gte=2,
                laboratory=True,
                pdzr__isnull=True,
                dzr__isnull=True,
                # sdl_set__tech__gt=0,
            ).select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            ),
        )
    if status == "waiting":
        return list(
            It_lab.objects.filter(
                ~Q(mpp_etap=mpp),
                (Q(mpp_etap__gt=0) | Q(id_etap=1)),
                dzr__isnull=True,
                laboratory=True,
            )
            .filter(
                Q(sdl_set__doc=mpp)
                | Q(sdl_set__tech=mpp)
                | Q(sdl_set__lit=mpp)
                | Q(sdl_set__pol=mpp),
            )
            .select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            ),
        )

    return list(It_lab.objects.none())


class DatesInDocNarsSchema(Schema):
    mpp: int
    dn_lg: str
    dk_lg: str
    dn_pl: str
    dk_pl: str


class NarsForDocReportsSchema(Schema):
    nkv: str
    dou: date
    dzr: date | None
    pdzr: date | None
    stu: float
    fio: str
    lpu__name_lpu: str


class CloseCommitDocNarsSchema(StatusMessage):
    pdzr_pl: list[NarsForDocReportsSchema] = None
    dzr_pl: list[NarsForDocReportsSchema] = None
    pdzr_lg: list[NarsForDocReportsSchema] = None
    dzr_lg: list[NarsForDocReportsSchema] = None


@router.post(
    "/nar_list_by_period/",
    response={
        200: CloseCommitDocNarsSchema,
        403: Error(message="Ошибка обработки запроса"),
    },
)
def nar_list_by_period(  # noqa: ANN201
    request,  # noqa: ARG001
    period: Form[DatesInDocNarsSchema],
):
    pdzr_pl = (
        It_lab.objects.filter(
            dzr__isnull=True,
            pdzr__isnull=False,
            sdl_set__doc=period.mpp,
            pdzr__range=(period.dn_pl, period.dk_pl),
            opl__opl__gt=1,
        )
        .annotate(
            fio=Concat(
                "patient__fam",
                Value(" "),
                "patient__im",
                Value(" "),
                "patient__ot",
            ),
        )
        .values(
            "nkv",
            "dou",
            "dzr",
            "pdzr",
            "stu",
            "fio",
            "lpu__name_lpu",
        )
    )
    dzr_pl = (
        It_lab.objects.filter(
            dzr__isnull=False,
            sdl_set__doc=period.mpp,
            dzr__range=(period.dn_pl, period.dk_pl),
            check_zav=True,
            check_tech=True,
            opl__opl__gt=1,
        )
        .annotate(
            fio=Concat(
                "patient__fam",
                Value(" "),
                "patient__im",
                Value(" "),
                "patient__ot",
            ),
        )
        .values(
            "nkv",
            "dou",
            "dzr",
            "pdzr",
            "stu",
            "fio",
            "lpu__name_lpu",
        )
    )
    pdzr_lg = (
        It_lab.objects.filter(
            dzr__isnull=True,
            pdzr__isnull=False,
            sdl_set__doc=period.mpp,
            pdzr__range=(period.dn_lg, period.dk_lg),
            opl__opl=1,
        )
        .annotate(
            fio=Concat(
                "patient__fam",
                Value(" "),
                "patient__im",
                Value(" "),
                "patient__ot",
            ),
        )
        .values(
            "nkv",
            "dou",
            "dzr",
            "pdzr",
            "stu",
            "fio",
            "lpu__name_lpu",
        )
    )
    dzr_lg = (
        It_lab.objects.filter(
            dzr__isnull=False,
            sdl_set__doc=period.mpp,
            dzr__range=(period.dn_lg, period.dk_lg),
            check_zav=True,
            check_tech=True,
            opl__opl=1,
        )
        .annotate(
            fio=Concat(
                "patient__fam",
                Value(" "),
                "patient__im",
                Value(" "),
                "patient__ot",
            ),
        )
        .values(
            "nkv",
            "dou",
            "dzr",
            "pdzr",
            "stu",
            "fio",
            "lpu__name_lpu",
        )
    )
    return 200, {
        "ok": True,
        "status": 200,
        "message": "nar_list_by_period success",
        "pdzr_pl": pdzr_pl,
        "dzr_pl": dzr_pl,
        "pdzr_lg": pdzr_lg,
        "dzr_lg": dzr_lg,
    }


@router.get(
    "/pl_uslp_list",
    response={200: list[UslSchema], 403: Error(message="Ошибка обработки запроса")},
)
def pl_uslp_list(request, idkv: str) -> list[UslSchema]:  # noqa: ARG001
    return list(Pl_uslp.objects.filter(idkv=idkv))


class EtapsSchema(Schema):
    id: int
    naryad: NaryadSchema
    etap: int
    dn: datetime
    dz: datetime
    user: UserSchema | None
    sdl: SdlSchema


class ContainerCustomSchema(Schema):
    container__id: int
    nkv: str
    dou: date
    stu: Decimal


class OneNarSchema(Schema):
    naryad: NaryadSchema
    prev_etaps: list[EtapsSchema] | None
    nar_containers: list[ContainerCustomSchema] | None


@router.get(
    "/one_nar/",
    response={200: OneNarSchema, 403: Error(message="Ошибка обработки запроса")},
)
def one_nar(
    request,  # noqa: ARG001
    naryad_id: int = 0,
    naryad_nkv: str = "",
) -> OneNarSchema:
    if naryad_id > 0:
        naryad = (
            It_lab.objects.filter(id=naryad_id)
            .select_related(
                "lpu",
                "patient",
                "opl",
                "sdl_etap",
                "sdl_set",
                "naryad_doc",
                "user_etap_link",
            )
            .first()
        )
        prev_etaps = list(Etaps.objects.filter(naryad__id=naryad_id))
        naryads = (
            It_lab.objects.exclude(nkv=naryad.nkv)
            .filter(
                patient=naryad.patient,
                naryad_doc=naryad.naryad_doc,
                dzr__isnull=True,
                pdzr__isnull=True,
                container__id__gt=0,
            )
            .values("container__id", "nkv", "dou", "stu")
        )
        nar_list_containers: list = list(naryads)
        return {
            "naryad": naryad,
            "prev_etaps": prev_etaps,
            "nar_containers": nar_list_containers,
        }
    naryad = (
        It_lab.objects.filter(nkv=naryad_nkv)
        .select_related(
            "lpu",
            "patient",
            "opl",
            "sdl_etap",
            "sdl_set",
            "naryad_doc",
            "user_etap_link",
        )
        .first()
    )
    prev_etaps = list(Etaps.objects.filter(naryad=naryad))
    naryads = (
        It_lab.objects.exclude(nkv=naryad.nkv)
        .filter(
            patient=naryad.patient,
            naryad_doc=naryad.naryad_doc,
            dzr__isnull=True,
            pdzr__isnull=True,
            container__id__gt=0,
        )
        .values("container__id", "nkv", "dou", "stu")
    )
    nar_list_containers: list = list(naryads)
    return {
        "naryad": naryad,
        "prev_etaps": prev_etaps,
        "nar_containers": nar_list_containers,
    }


@router.get(
    "/get_container/",
    response={200: bool, 403: Error(message="Ошибка обработки запроса")},
)
def get_container(request, container: int) -> bool:  # noqa: ARG001
    if 1 <= container <= 1000:  # noqa: PLR2004
        cont: Container = Container.objects.get(id=container)
        if cont.used:
            count: int = It_lab.objects.filter(
                nkv=cont.nkv,
                dzr__isnull=True,
                pdzr__isnull=True,
            ).count()
            if count > 0:
                return False
        return True
    return False


@router.get(
    "/move_naryad/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
def move_naryad(  # noqa: ANN201
    request,  # noqa: ARG001
    naryad_id: int,
    sdl: int,
    mpp: int,
    container: int = 0,
):
    try:
        if container == 999:  # noqa: PLR2004
            cont = Container.objects.get(id=999)
            cont.used = False
            cont.nkv = 0
            cont.save()
        naryad = It_lab.objects.get(id=naryad_id)
        if not naryad_move(naryad, sdl, mpp, container):
            return 403
        if container == 999:  # noqa: PLR2004
            cont = Container.objects.get(id=999)
            cont.used = False
            cont.nkv = "0"
            cont.save()
    except (ObjectDoesNotExist, MultipleObjectsReturned):
        logging.exception("naryad_move")
        return 403
    except Exception:  # noqa: BLE001
        return 403
    else:
        return 200, {"ok": True, "status": 200, "message": "naryad_mooved"}


@router.get(
    "/naryad_close/",
    response={200: StatusMessage, 403: Message},
)
def naryad_close(request, naryad_id: int):  # noqa: ARG001, ANN201
    try:
        naryad = It_lab.objects.get(id=naryad_id)
        if not naryad_close_by_doc(naryad):
            return 400
    except (ObjectDoesNotExist, MultipleObjectsReturned):
        logging.exception("naryad_close")
        return 400
    except Exception:
        logging.exception("naryad_close another error")
        return 400
    else:
        return 200, {"ok": True, "status": 200, "message": "naryad_close"}


@router.get(
    "/close_ortodont_by_st/",
    response={200: StatusMessage, 403: Message},
)
def close_ortodont_by_st(request, naryad_id: int, date_close: date):  # noqa: ARG001, ANN201
    print(type(date_close), date_close)
    try:
        naryad = It_lab.objects.filter(id=naryad_id).first()
        print(naryad)
        naryad = It_lab.objects.get(id=naryad_id)
        if not naryad_close_by_st_custom_date(naryad=naryad, date_close=date_close):
            return 400
    except (ObjectDoesNotExist, MultipleObjectsReturned):
        logging.exception("naryad_close")
        return 400
    except Exception:
        logging.exception("naryad_close another error")
        return 400
    else:
        return 200, {"ok": True, "status": 200, "message": "naryad_close"}


class AddImageInSchema(Schema):
    naryad_id: int
    image: UploadedFile = File()


@router.post(
    "/image_add/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
def image_add(  # noqa: ANN201
    request,  # noqa: ARG001
    image: File[UploadedFile],
    naryad_id: Form[int],
):
    naryad = It_lab.objects.get(id=naryad_id)
    Images.objects.create(img=image, etap=naryad, naryad=naryad.nkv)
    naryad.image_count += 1
    naryad.save()
    return 200, {"ok": True, "status": 200, "message": "image_add"}


@router.post(
    "/add_comment",
    response={200: StatusMessage, 403: Message},
)
def add_comment(  # noqa: ANN201
    request,  # noqa: ARG001
    naryad_id: Form[int],
    comment: Form[str],
    mpp: Form[int],
):
    try:
        naryad = It_lab.objects.get(id=naryad_id)
        if naryad.id_etap == 1:
            Comments.objects.create(
                naryad=naryad,
                user=MyUser.objects.get(mpp=mpp),
                sdl=Spr_sdl.objects.get(sdl=3500),
                comment=comment,
            )
        else:
            Comments.objects.create(
                naryad=naryad,
                user=MyUser.objects.get(mpp=mpp),
                sdl=naryad.sdl_etap,
                comment=comment,
            )
    except Exception:  # noqa: BLE001
        return 403, {"message": "Error add comment"}
    return 200, {"ok": True, "status": 200, "message": "add comment completed"}


class CommentSchema(Schema):
    naryad: NaryadSchema
    date: datetime
    user: UserSchema | None
    sdl: SdlSchema
    comment: str


@router.get("/comments_list", response={200: list[CommentSchema]})
def comments_list(request, naryad_id: int) -> list[CommentSchema]:  # noqa: ARG001
    naryad = It_lab.objects.get(id=naryad_id)
    return Comments.objects.filter(naryad=naryad).order_by("-id")


class PostLpuSchema(Schema):
    lpu: int
    name_lpu: str
    adress: str


class PostPatientSchema(Schema):
    uid: int
    fam: str
    im: str
    ot: str
    dr: date
    adress: str


class PostUslugiSchema(Schema):
    kusl: str
    kol: int
    price: Decimal


class PostOplSchema(Schema):
    opl: int
    name_opl: str


class PostNaryadSchema(Schema):
    lpu: PostLpuSchema
    patient: PostPatientSchema
    idkv: str
    nkv: str
    dou: date
    laboratory: int = None
    profile_otd: int = None
    stu: Decimal
    opl: PostOplSchema
    doc: int
    uslugi: list[PostUslugiSchema]


@router.post("/post_naryad/{int:mpp}", response={200: StatusMessage, 201: StatusMessage, 403: Message, 401: Message, 404: Message, 405: Message, 406: Message})
def post_naryad(request, mpp: int, naryad: PostNaryadSchema):  # noqa: ANN201, ARG001, C901, PLR0912
    user = MyUser.objects.get(mpp=mpp)
    with set_actor(user):
        if Spr_lpu.objects.filter(lpu=naryad.lpu.lpu).exists():
            lpu = Spr_lpu.objects.get(lpu=naryad.lpu.lpu)
        else:
            lpu = Spr_lpu.objects.create(**naryad.lpu.dict())
        if Spr_opl.objects.filter(opl=naryad.opl.opl).exists():
            opl = Spr_opl.objects.get(opl=naryad.opl.opl)
        else:
            opl = Spr_opl.objects.create(**naryad.opl)
        if Patient.objects.filter(uid=naryad.patient.uid, fam=naryad.patient.fam, dr=naryad.patient.dr).exists():
            patient = Patient.objects.get(uid=naryad.patient.uid)
        else:
            patient = Patient.objects.create(**naryad.patient.dict())
        if It_lab.objects.filter(nkv=naryad.nkv).exists():
            nar_db = It_lab.objects.get(nkv=naryad.nkv)
            if nar_db.dzr is not None or nar_db.pdzr is not None:
                return  406, {"message": "Naryad already exist and have pdzr or dzr"}
            Pl_uslp.objects.filter(naryad=nar_db).delete()
            nar_db.stu=naryad.stu
            nar_db.save()
            for usl in naryad.uslugi:
                usluga = Uslugi.objects.get(kusl=usl.kusl)
                Pl_uslp.objects.create(
                    idkv=nar_db.nkv,
                    naryad=nar_db,
                    kusl=usluga.kusl,
                    usl=usluga.usl,
                    nusl=usluga.nusl,
                    kol=usl.kol,
                    uet=usluga.uet,
                    price=usluga.trf,
                )
            logging.warning(f"Naryad already exist {naryad.nkv}")
            return 201, {"ok": True, "status": 201, "message": "uslugi_updated"}
        naryad_doc = User_sdl.objects.filter(doc=naryad.doc).first()
        if naryad_doc is None:
            logging.warning(f"No exist doctor with doc {naryad.doc}")
            return 405, {"message": f"No exist doctor with doc {naryad.doc}"}
        user_etap_link = naryad_doc.user
        access = naryad_doc.access_list()
        profile_otd = 0
        if "doc" in access or "zav_ort" in access:
            profile_otd = 2
        elif "doc-ortodont" in access:
            profile_otd = 3
        naryad_db = It_lab.objects.create(
            lpu=lpu,
            patient=patient,
            idkv=naryad.nkv,
            nkv=naryad.nkv,
            dou=naryad.dou,
            stu=naryad.stu,
            user_etap_link=user_etap_link,
            naryad_doc=naryad_doc,
            profile_otd=profile_otd,
            laboratory=False,
            opl=opl,
            sdl_etap=Spr_sdl.objects.get(sdl=1),
            sdl_set=Sdl_set.objects.create(doc=user_etap_link.mpp),
            container=Container.objects.get(id=0),
        )
        # naryad_db.refresh_from_db()
        # usls_in_db = Pl_uslp.objects.filter(nkv=naryad_db.nkv)
        # summa = 0
        # for usl_in_db in usls_in_db:
        #     usluga = Uslugi.objects.filter(kusl=usl_in_db.kusl).first()
        #     if usluga is None:
        #         print(usl_in_db, "Usluga not found")
        #     else:
        #         summa += usluga.trf * usl_in_db.kol
        # if naryad.stu != summa:
        #     return 406, {"message": f"summa in usl {summa} not equal stu {naryad.stu} document {naryad.doc}"}
        for usl in naryad.uslugi:
            usluga = Uslugi.objects.get(kusl=usl.kusl)
            Pl_uslp.objects.create(
                idkv=naryad_db.nkv,
                naryad=naryad_db,
                kusl=usluga.kusl,
                usl=usluga.usl,
                nusl=usluga.nusl,
                kol=usl.kol,
                uet=usluga.uet,
                price=usluga.trf,
            )
        return 200, {"ok": True, "status": 200, "message": "post_naryad success"}


class DocOpenDictSchema(Schema):
    mpp: int
    name: str
    count_open: int
    sum_open: float
    avg_days_open: float
    count_pdzr: int
    sum_pdzr: float
    avg_days_pdzr: float


class LpuDictSchema(Schema):
    lpu_id: int
    lpu: LpuSchema
    doc_list: list[DocOpenDictSchema]


class StatusMessageOpenNars(Schema):
    ok: bool
    status: int
    message: str
    lpu_list: list[LpuDictSchema]


@router.get("/open_naryads/", response={200: StatusMessageOpenNars, 403: StatusMessage})
def open_naryads(request, mpp):  # noqa: ARG001, ANN201
    try:
        access_list = [
            Spr_access.objects.get(access="doc"),
            Spr_access.objects.get(access="zav_ort"),
        ]
        open_naryads = It_lab.objects.filter(
            dzr__isnull=True,
            check_zav=False,
            naryad_doc__access__in=access_list,
        )
        lpu_id_set = {value.lpu.lpu for value in open_naryads}
        lpu_list = []
        for lpu_id in lpu_id_set:
            docs_list = []
            open_naryads_lpu = open_naryads.filter(lpu__lpu=lpu_id)
            docs_mpp_set = {naryad.naryad_doc.user.mpp for naryad in open_naryads_lpu}
            for doc_mpp in docs_mpp_set:
                naryads_doc = open_naryads_lpu.filter(naryad_doc__user__mpp=doc_mpp)
                naryads_doc_open = naryads_doc.filter(pdzr__isnull=True)
                naryads_doc_pdzr = naryads_doc.filter(pdzr__isnull=False)
                days_open = [
                    int((date.today() - nar.dou).days) for nar in naryads_doc_open
                ]
                sum_open = [Decimal(v.stu) for v in naryads_doc_open]
                days_pdzr = [
                    int((date.today() - nar.dou).days) for nar in naryads_doc_pdzr
                ]
                sum_pdzr = [Decimal(v.stu) for v in naryads_doc_pdzr]
                print(doc_mpp)
                doc_dict = {
                    "mpp": doc_mpp,
                    "name": MyUser.objects.get(mpp=doc_mpp).get_full_name(),
                    "count_open": naryads_doc_open.count(),
                    "sum_open": sum(sum_open),
                    "avg_days_open": (
                        math.ceil(sum(days_open) / len(days_open))
                        if len(days_open) > 0
                        else 0
                    ),
                    "count_pdzr": naryads_doc_pdzr.count(),
                    "sum_pdzr": sum(sum_pdzr),
                    "avg_days_pdzr": (
                        math.ceil(sum(days_pdzr) / len(days_pdzr))
                        if len(days_pdzr) > 0
                        else 0
                    ),
                }
                docs_list.append(doc_dict)

            lpu_dict = {
                "lpu_id": lpu_id,
                "lpu": Spr_lpu.objects.get(lpu=lpu_id),
                "doc_list": docs_list,
            }
            lpu_list.append(lpu_dict)
    except Exception:
        logging.exception("Open_naryads_error")
    return 200, {
        "ok": True,
        "status": 200,
        "message": "open naryads list success",
        "lpu_list": lpu_list,
    }


class ContainerSchema(Schema):
    used: bool
    nkv: str | None


class IdLastSchema(Schema):
    number: int


@router.get(
    "/open_naryads_by_doc/",
    response={200: list[NaryadSchema], 403: StatusMessage},
)
def open_naryads_by_doc(request, mpp, lpu):  # noqa: ANN201, ARG001
    try:
        naryads = It_lab.objects.filter(
            naryad_doc__user__mpp=mpp,
            dzr__isnull=True,
            check_zav=False,
            lpu__lpu=lpu,
        )
    except Exception:
        logging.exception("Open_naryads_error")
    return list(naryads)


class UnworkSchema(Schema):
    cast: date
    cast1: date | datetime = None
    doc: int
    iblc: int
    nrsn_: str = None
    rsn: int


class GraphSchema(Schema):
    doc: int
    even_day: str
    fam: str
    even_day: str
    noeven_day: str
    im: str
    lpu: int
    nslp: str
    nlist: int
    nroom_kr: str | None = None
    nspz: str | None = None
    ntv: int
    ot: str
    room: int
    spz: int
    unwork: list[UnworkSchema] = None
    is_unwork: bool = None
    is_unwork_soon: bool = None
    date1_unwork: date = None
    date2_unwork: date = None
    rsn_unwork: str = None


class StatusMessageGraphSchema(Schema):
    ok: bool
    status: int
    message: str
    graph_list: list[GraphSchema]


@router.get(
    "/rasp_all/",
    response={200: StatusMessageGraphSchema, 403: StatusMessage},
)
def rasp_all(request):  # noqa: PLR0912, ANN201, C901, ARG001
    try:
        result1 = db.sel_dict_in_list_lowerkeys(
            """select distinct n_doc.doc, n_mpp.fam, n_mpp.im, n_mpp.ot, n_doc.dolj,(select ndlj from n_dlj where dlj=n_doc.dolj)
from n_mpp, n_doc
where n_mpp.mpp=n_doc.mpp
 and (n_doc.pv=1)
 and n_doc.sdl = 1
 and n_doc.pv = 1
 and n_doc.vid_priema>0
 and n_doc.mpp>0
 and n_doc.mol = 1
order by fam,im,ot""",
        )
        docs_doc = (*{doc["doc"] for doc in result1},)
        dict_doc = {}
        for doc in result1:
            dict_doc[doc["doc"]] = doc
        result3 = db.select(
            f"""Select doc, iblc, CAST (dtn AS date), CAST (dtk AS date), rsn, (select nrsn from rsp_rsn where rsp_rsn.rsn=rsp_blc.rsn) as nrsn_
 from rsp_blc
where doc in {docs_doc} and (rsp_blc.dtk>='01.01.2024' and rsp_blc.dtk<='31.12.2024') order by dtn desc""",  # noqa: S608
        )
        result3 = [
            {
                "doc": x[0],
                "iblc": x[1],
                "cast": x[2],
                "cast1": x[3],
                "rsn": x[4],
                "nrsn_": (
                    x[5].replace("\n", " ").replace("\r", "").strip()
                    if x[5] is not None
                    else ""
                ),
            }
            for x in result3
            if x[3] >= date.today()
        ]
        dict_unwork = {}
        for doc in result3:
            list_unwork = []
            if doc["doc"] in dict_unwork:
                list_unwork = dict_unwork[doc["doc"]]
                list_unwork.append(doc)
                dict_unwork[doc["doc"]] = list_unwork
            else:
                dict_unwork[doc["doc"]] = [doc]
        result = db.sel_dict_in_list_lowerkeys(
            f"""Select doc, IT_RASP.LPU,(select nslp from n_slp where slp=it_rasp.lpu),IT_RASP.ROOM,
                        ROOM.NROOM_KR,
                        IT_RASP.ID_INTERVAL1,
                        (select interval_time from it_rasp_time where it_rasp_time.id=it_rasp.ID_INTERVAL1) as NOEVEN_DAY,
                        IT_RASP.ID_INTERVAL2,
                        (select interval_time from it_rasp_time where it_rasp_time.id=it_rasp.ID_INTERVAL2) as EVEN_DAY,
                        IT_RASP.NTV,
                        IT_RASP.NLIST,
                        IT_RASP.SPZ,
                        N_SPZ.NSPZ
                 from IT_RASP, ROOM, N_SPZ
                 where (it_rasp.room=room.id) and (it_rasp.spz=n_spz.spz) and doc in {docs_doc}""",  # noqa: S608
        )

        for one in dict_unwork.items():
            if len(one) > 1:
                one[1].sort(key=lambda item: item["cast"])

        for docs in result:
            docs["fam"] = dict_doc[docs["doc"]]["fam"]
            docs["im"] = dict_doc[docs["doc"]]["im"]
            docs["ot"] = dict_doc[docs["doc"]]["ot"]
            if docs["doc"] in dict_unwork:
                list_unwork = dict_unwork[docs["doc"]]
                for unwork in list_unwork:
                    if unwork["cast1"] < date.today():
                        continue
                    if "is_unwork" in docs and docs["is_unwork"] is True:
                        break
                    if unwork["cast"] <= date.today() <= unwork["cast1"]:
                        docs["is_unwork"] = True
                        docs["date1_unwork"] = unwork["cast"]
                        docs["date2_unwork"] = unwork["cast1"]
                        docs["rsn_unwork"] = unwork["nrsn_"]
                    if (
                        unwork["cast"] > date.today()
                        and (unwork["cast"] - date.today()).days <= 7  # noqa: PLR2004
                    ):

                        docs["is_unwork_soon"] = True

                else:
                    if "is_unwork" not in docs:
                        docs["is_unwork"] = False
                    if "is_unwork_soon" not in docs:
                        docs["is_unwork_soon"] = False
                docs["unwork"] = list_unwork

        result = [
            x for x in result if x["even_day"] != "РќРџ" and x["noeven_day"] != "РќРџ"
        ]
        result.sort(key=lambda item: item["fam"])
        pprint.pprint(result)
        for nar in result:
            if nar['nslp'] is None:
                print(nar)
            # print(nar['nslp'])
    except Exception:
        logging.exception("Open_naryads_error")
    return 200, {
        "ok": True,
        "status": 200,
        "message": "open naryads list success",
        "graph_list": result,
    }


class UserProfSchema(Schema):
    id: int
    name: str
    mpp: int


class StatusListAllProfSchema(Schema):
    ok: bool
    status: int
    message: str
    list_tech: list[UserProfSchema]
    list_lit: list[UserProfSchema]
    list_cadcam: list[UserProfSchema]
    list_pol: list[UserProfSchema]


@router.get(
    "/list_all_prof/",
    response={200: StatusListAllProfSchema, 403: StatusMessage},
)
def list_all_prof(request):  # noqa: ANN201, ARG001
    dict_zero = {"id": 0, "name": "He назначен", "mpp": 0}
    list_tech = User_sdl.objects.filter(access__access="tech")
    tech_list = [dict_zero]
    for tech in list_tech:
        new_dict = {
            "id": tech.user.id,
            "name": tech.user.get_full_name(),
            "mpp": tech.user.mpp,
        }
        tech_list.append(new_dict)
    tech_list.sort(key=lambda item: item["name"])
    list_lit = User_sdl.objects.filter(access__access="lit")
    lit_list = [dict_zero]
    for lit in list_lit:
        new_dict = {
            "id": lit.user.id,
            "name": lit.user.get_full_name(),
            "mpp": lit.user.mpp,
        }
        lit_list.append(new_dict)
    lit_list.sort(key=lambda item: item["name"])
    list_cadcam = User_sdl.objects.filter(access__access="cad")
    cadcam_list = [dict_zero]
    for cadcam in list_cadcam:
        new_dict = {
            "id": cadcam.user.id,
            "name": cadcam.user.get_full_name(),
            "mpp": cadcam.user.mpp,
        }
        cadcam_list.append(new_dict)
    cadcam_list.sort(key=lambda item: item["name"])
    list_pol = User_sdl.objects.filter(access__access="pol")
    pol_list = [dict_zero]
    for pol in list_pol:
        new_dict = {
            "id": pol.user.id,
            "name": pol.user.get_full_name(),
            "mpp": pol.user.mpp,
        }
        pol_list.append(new_dict)
    pol_list.sort(key=lambda item: item["name"])
    return 200, {
        "ok": True,
        "status": 200,
        "message": "list all prof success",
        "list_tech": tech_list,
        "list_lit": lit_list,
        "list_cadcam": cadcam_list,
        "list_pol": pol_list,
    }


class StatusListAllDocSchema(Schema):
    ok: bool
    status: int
    message: str
    list_doc: list[UserProfSchema]


@router.get(
    "/list_all_doc/",
    response={200: StatusListAllDocSchema, 403: StatusMessage},
)
def list_all_doc(request):  # noqa: ANN201, ARG001
    dict_zero = {"id": 0, "name": "He назначен", "mpp": 0}
    list_tech = User_sdl.objects.filter(access__access="doc")
    doc_list = [dict_zero]
    for doc in list_tech:
        new_dict = {
            "id": doc.user.id,
            "name": doc.user.get_full_name(),
            "mpp": doc.user.mpp,
        }
        doc_list.append(new_dict)
    doc_list.sort(key=lambda item: item["name"])
    return 200, {
        "ok": True,
        "status": 200,
        "message": "list all doc success",
        "list_doc": doc_list,
    }


class SdlSetUpdateSchema(Schema):
    naryad_id: int
    tech: int
    lit: int
    pol: int
    cadcam: int


@router.post(
    "/sdl_set_update/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
def sdl_set_update(request, new_sdl: Form[SdlSetUpdateSchema]):  # noqa: ANN201, ARG001
    naryad = It_lab.objects.get(id=new_sdl.naryad_id)
    sdl_set: Sdl_set = naryad.sdl_set
    sdl_set.tech = new_sdl.tech
    sdl_set.lit = new_sdl.lit
    sdl_set.pol = new_sdl.pol
    sdl_set.cadcam = new_sdl.cadcam
    sdl_set.save()
    sdl = naryad.sdl_etap.sdl
    user_etap = naryad.user_etap_link
    match sdl:
        case 35:
            if user_etap.mpp != sdl_set.tech:
                user =  MyUser.objects.get(mpp=sdl_set.tech)
                naryad.user_etap_link = user
                naryad.user_etap = user.login
                naryad.save()
        case 37:
            if user_etap.mpp!= sdl_set.lit:
                user =  MyUser.objects.get(mpp=sdl_set.lit)
                naryad.user_etap_link = user
                naryad.user_etap = user.login
                naryad.save()
        case 36:
            if user_etap.mpp!= sdl_set.pol:
                user =  MyUser.objects.get(mpp=sdl_set.pol)
                naryad.user_etap_link = user
                naryad.user_etap = user.login
                naryad.save()
        case 38:
            if user_etap.mpp!= sdl_set.cadcam:
                user =  MyUser.objects.get(mpp=sdl_set.cadcam)
                naryad.user_etap_link = user
                naryad.user_etap = user.login
                naryad.save()
    return 200, {"ok": True, "status": 200, "message": "sdl set update success"}


@router.get(
    "/used_usl/",
    response={200: StatusMessage, 403: Error(message="Ошибка обработки запроса")},
)
def used_usl(request):  # noqa: ANN201, ARG001
    uslugi_dict = {}
    naryads = It_lab.objects.all()
    for nar in naryads:
        for usl in Pl_uslp.objects.filter(naryad=nar):
            if usl.kusl in uslugi_dict:
                uslugi_dict[usl.kusl] += 1
            else:
                uslugi_dict[usl.kusl] = 1
    return uslugi_dict


class PeriodDate(Schema):
    id: int
    nmonth: str
    dn_pl: date
    dk_pl: date
    dn_lg: date
    dk_lg: date
    years: int
    months: int
    disable: bool = None


@router.get(
    "/period_date/",
    response={
        200: list[PeriodDate],
        403: StatusMessage,
    },
)
def period_date(request):  # noqa: ANN201, ARG001
    select_dates = "select id, nmonth, dn_pl, dk_pl, dn_lg, dk_lg, years, months from it_period_rep where razdel=1 and id >= 28"
    date_zero = {
        "id": 0,
        "nmonth": "Выбрать период",
        "dn_pl": "2022-05-26T00:00:00",
        "dk_pl": "2022-06-25T00:00:00",
        "dn_lg": "2022-05-21T00:00:00",
        "dk_lg": "2022-06-20T00:00:00",
        "years": 2022,
        "months": 6,
        "disable": True,
    }
    dates = db.sel_dict_in_list_lowerkeys(select_dates)
    sorted_dates = sorted(dates, key=lambda item: item["id"])
    return [date_zero, *sorted_dates]


class OneNarUslForCloseSchema(Schema):
    nkv: int
    sdl_set__doc: str
    stu: float
    doctor: str
    dou: str
    dzr: date
    pdzr: date


class NaryadUslDocOneSchema(StatusMessage):
    doc_mpp: int
    laboratory: bool


@router.get(
    "/naryad_usl_doc_one/",
    response={
        200: NaryadUslDocOneSchema,
        203: StatusMessage,
    },
)
def naryad_usl_doc_one(request, nkv: str = ""):  # noqa: ANN201, ARG001
    naryad = It_lab.objects.filter(nkv=nkv).first()
    if naryad is None:
        return 203, {
            "ok": False,
            "status": 203,
            "message": "Такого наряда не найдено",
        }
    if naryad.dzr is not None:
        return 203, {
            "ok": False,
            "status": 203,
            "message": f"Наряд №{naryad.nkv} уже закрыт {naryad.dzr}",
        }
    if naryad.pdzr is not None:
        return 203, {
            "ok": False,
            "status": 203,
            "message": f"Наряд №{naryad.nkv} уже отправлен на проверку {naryad.pdzr}",
        }
    return 200, {
        "ok": True,
        "status": 200,
        "message": f"Наряд №{naryad.nkv}. Врач {MyUser.objects.get(mpp=naryad.sdl_set.doc).get_full_name()}. Наряд на сумму {naryad.stu} руб. от {naryad.dou}",
        "doc_mpp": naryad.sdl_set.doc,
        "laboratory": naryad.laboratory,
    }


@router.get("/close_usl/", response={200: StatusMessage})
def close_usl(request, nkv: str = "", mpp: int = 0):  # noqa: ANN201, ARG001
    naryad = It_lab.objects.filter(nkv=nkv).first()
    if naryad.sdl_set.doc == mpp:
        naryad.pdzr = timezone.now()
        naryad.save()
        return 200, {
            "ok": True,
            "status": 200,
            "message": "Успешно закрыт наряд без лаборатории",
        }
    return 200, {
        "ok": False,
        "status": 200,
        "message": "Ошибка закрытия наряда",
    }


@router.get("/mpp_podr_list/")
def mpp_podr_list(request, mpp: int):  # noqa: ANN201, ARG001
    user = MyUser.objects.filter(mpp=mpp).first()
    mpp_podr = Mpp_podr.objects.filter(mpp=user).first()
    list_zero = {"lpu_name": "Все подразделения", "lpu_number": 0, "disabled": True}
    list_podr = mpp_podr.podr
    if user is not None and list_podr is not None:
        return [list_zero, *list_podr]
    return [list_zero]


class GetStatForZavSchemaIn(Schema):
    dn: date
    dk: date
    year: int
    month: int
    lgot: str
    podr: int
    profile: int = 2


class OneNaryadDocZavSchemaOut(Schema):
    id: int
    nkv: str
    stu: float
    dou: date
    pdzr: date
    patient__fam: str
    patient__im: str
    patient__ot: str


class OneDocZavSchemaOut(Schema):
    mpp: int
    fio: str
    lab_pdzr_zav: list[OneNaryadDocZavSchemaOut]
    lab_pdzr_tech: list[OneNaryadDocZavSchemaOut]
    usl_pdzr_zav: list[OneNaryadDocZavSchemaOut]
    usl_pdzr_tech: list[OneNaryadDocZavSchemaOut]
    lab_dzr: list[OneNaryadDocZavSchemaOut]
    usl_dzr: list[OneNaryadDocZavSchemaOut]


class DocsZavReportOut(StatusMessage):
    doc_list: list[OneDocZavSchemaOut]
    year: int
    month: int
    lgot: str
    dn: date
    dk: date


@router.post("/get_stat_for_zav2/", response={200: DocsZavReportOut})
def get_stat_for_zav2(  # noqa: ANN201
    request,  # noqa: ARG001
    report: Form[GetStatForZavSchemaIn],  # noqa: ARG001, RUF100
):
    year = report.year
    month = report.month
    lgot = report.lgot
    dn = report.dn
    dk = report.dk
    podr = report.podr
    profile = report.profile
    if lgot == "lgot":
        nars = It_lab.objects.filter(
            opl__opl=1,
            lpu__lpu=podr,
            pdzr__range=(dn, dk),
        ).order_by("dou")
    elif lgot == "pd":
        nars = It_lab.objects.filter(
            opl__opl__gt=1,
            profile_otd=profile,
            lpu__lpu=podr,
            pdzr__range=(dn, dk),
        ).order_by("dou")
    doc_list = []
    doc_set = set()
    for nar in nars:
        doc_set.add(nar.naryad_doc.user.mpp)
    for doc in doc_set:
        dict_for_one_doc = {}
        if lgot == "lgot":
            nars_one_doc_lab_pdzr_zav = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=True,
                dzr__isnull=True,
                check_zav=False,
                check_tech=False,
                opl__opl=1,
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_lab_pdzr_tech = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=True,
                dzr__isnull=True,
                check_zav=True,
                check_tech=False,
                opl__opl=1,
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_lab_dzr = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=True,
                check_zav=True,
                check_tech=True,
                opl__opl=1,
                dzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_pdzr_zav = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=False,
                dzr__isnull=True,
                check_zav=False,
                check_tech=False,
                opl__opl=1,
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_pdzr_tech = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=False,
                dzr__isnull=True,
                check_zav=True,
                check_tech=False,
                opl__opl=1,
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_dzr = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                lpu__lpu=podr,
                laboratory=False,
                opl__opl=1,
                dzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
        elif lgot == "pd":
            nars_one_doc_lab_pdzr_zav = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=True,
                dzr__isnull=True,
                check_zav=False,
                check_tech=False,
                opl__opl__in=(3, 5, 10),
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_lab_pdzr_tech = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=True,
                dzr__isnull=True,
                check_zav=True,
                check_tech=False,
                opl__opl__in=(3, 5, 10),
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_lab_dzr = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=True,
                check_zav=True,
                check_tech=True,
                opl__opl__in=(3, 5, 10),
                dzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_pdzr_zav = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=False,
                dzr__isnull=True,
                check_zav=False,
                check_tech=False,
                opl__opl__in=(3, 5, 10),
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_pdzr_tech = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=False,
                dzr__isnull=True,
                check_zav=True,
                check_tech=False,
                opl__opl__in=(3, 5, 10),
                pdzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
            nars_one_doc_usl_dzr = It_lab.objects.filter(
                naryad_doc__user__mpp=doc,
                profile_otd=profile,
                lpu__lpu=podr,
                laboratory=False,
                opl__opl__in=(3, 5, 10),
                dzr__range=(dn, dk),
            ).values(
                "id",
                "nkv",
                "stu",
                "dou",
                "pdzr",
                "patient__fam",
                "patient__im",
                "patient__ot",
            )
        dict_for_one_doc["mpp"] = doc
        dict_for_one_doc["fio"] = MyUser.objects.get(mpp=doc).get_full_name()
        dict_for_one_doc["lab_pdzr_zav"] = nars_one_doc_lab_pdzr_zav
        dict_for_one_doc["lab_pdzr_tech"] = nars_one_doc_lab_pdzr_tech
        dict_for_one_doc["usl_pdzr_zav"] = nars_one_doc_usl_pdzr_zav
        dict_for_one_doc["usl_pdzr_tech"] = nars_one_doc_usl_pdzr_tech
        dict_for_one_doc["lab_dzr"] = nars_one_doc_lab_dzr
        dict_for_one_doc["usl_dzr"] = nars_one_doc_usl_dzr
        doc_list.append(dict_for_one_doc)
        # doc_list_sorted = (
        #     sorted(doc_list, key=lambda x: x["fio"]) if len(doc_list) > 1 else doc_list
        # )
    return {
        "ok": True,
        "status": 200,
        "message": "Наряды найдены",
        "year": year,
        "month": month,
        "lgot": lgot,
        "dn": dn,
        "dk": dk,
        "doc_list": sorted(doc_list, key=lambda x: x["fio"]) if len(doc_list) > 1 else doc_list,
    }


class ZavReportFinishInSchema(Schema):
    mpp: int
    nars_lab_all: str = None
    nars_lab_ok: str = None
    usl_numbers_all: str = None
    nars_usl_ok: str = None
    dn: date
    dk: date
    opl: str
    year: int
    month: int


@router.post("/zav_report_finish/", response={200: StatusMessage})
def zav_report_finish(  # noqa: ANN201
    request,  # noqa: ARG001
    input_data: Form[ZavReportFinishInSchema],
):
    # dn = input_data.dn  # noqa: ERA001
    # dk = input_data.dk  # noqa: ERA001
    opl = input_data.opl
    opl = "1" if opl == "lgot" else "10,5,3"
    # year = input_data.year  # noqa: ERA001
    # month = input_data.month  # noqa: ERA001
    # mpp = input_data.mpp  # noqa: ERA001
    nars_lab_all = json.loads(input_data.nars_lab_all)
    usl_numbers = json.loads(input_data.usl_numbers_all)
    nars_lab_ok = json.loads(input_data.nars_lab_ok)
    nars_usl_ok = json.loads(input_data.nars_usl_ok)

    nar_list = []
    # nar_list = [x["nkv"] for x in nars_lab_ok]  # noqa: ERA001
    for one_nar in nars_lab_ok:
        nar_list.append(one_nar["nkv"])  # noqa: PERF401
    # nar_list.extend(x["nkv"] for x in nars_usl_ok)  # noqa: ERA001
    for one_usl in nars_usl_ok:
        nar_list.append(one_usl["nkv"])  # noqa: PERF401
    It_lab.objects.filter(nkv__in=nar_list).update(
        check_zav=True,
        dz_etap=timezone.now(),
    )
    list_cancel = list(set(nars_lab_all + usl_numbers) - set(nar_list))

    It_lab.objects.filter(nkv__in=list_cancel).update(
        check_zav=False,
        pdzr=None,
        dz_etap=None,
    )
    return 200, {"ok": True, "status": 200, "message": "Наряды подтверждены/отменены"}


class SpecFromNarOutSchema(StatusMessage):
    doc: int
    tech: int
    pol: int
    lit: int
    cadcam: int


@router.get("/get_spec_from_nar/", response={200: SpecFromNarOutSchema})
def get_spec_from_nar(request, nkv: str):  # noqa: ANN201, ARG001
    naryad = It_lab.objects.get(nkv=nkv)
    sdl: Sdl_set = naryad.sdl_set
    return {
        "ok": True,
        "status": 200,
        "message": "Успешно получен список специалистов",
        "doc": sdl.doc,
        "tech": sdl.tech,
        "pol": sdl.pol,
        "lit": sdl.lit,
        "cadcam": sdl.cadcam,
    }


@router.get("/finish_naryad/", response={200: StatusMessage})
# # @login_for_logs_by_mpp
def finish_naryad(request, nkv: str, year: int, month: int, profile: int, mpp: int):  # noqa: ANN201, ARG001
    print(year, month, profile, mpp)
    naryad = It_lab.objects.get(nkv=nkv)
    naryad.dzr = naryad.pdzr
    naryad.check_tech = True
    naryad.save()
    Buhreport.objects.filter(year=year, month=month, profile=profile).delete()
    return {"ok": True, "status": 200, "message": "Успешно закрыт"}




class ResponseZpSumSchemaSoec(Schema):
    mpp: int
    fio: str
    dolzh: str
    lab_lgot: float
    lab_vt: float
    lab_pd: float
    lab_itog: float


class ResponseZpSumSchemaDoc(ResponseZpSumSchemaSoec):
    usl_lgot: float
    usl_vt: float
    usl_pd: float
    usl_itog: float


class ResopnseZpSpecSchema(Schema):
    fio: str
    dolzh: str
    zp_lgot: float
    zp_vt: float
    zp_pd: float
    zp_itog: float

class ResponseZPAllSchema(StatusMessage):
    docs: list[ResponseZpSumSchemaDoc] | list
    techs: list[ResponseZpSumSchemaSoec] | list
    pols: list[ResponseZpSumSchemaSoec] | list
    lits: list[ResponseZpSumSchemaSoec] | list
    cadcams: list[ResponseZpSumSchemaSoec] | list
    zp_techs: list[ResponseZpSumSchemaSoec] | list
    zp_pols: list[ResponseZpSumSchemaSoec] | list
    zp_lits: list[ResponseZpSumSchemaSoec] | list
    zp_cadcams: list[ResponseZpSumSchemaSoec] | list
    file: str


class BuhZpSchemaIn(Schema):
    dn_lg: str
    dk_lg: str
    dn_pl: str
    dk_pl: str
    year: int
    month: int
    podr: int = 0
    profile: int = 2

@router.post("/buh_zp/", response={200: ResponseZPAllSchema})
def buh_zp(request, post_var: Form[BuhZpSchemaIn]) -> ResponseZPAllSchema:  # noqa: ARG001
    if post_var.podr > 1:
        result = Buhreport.objects.filter(year=post_var.year, month=post_var.month, podr=post_var.podr, profile=post_var.profile).first()
        if result is None:
            create_buh_report(year=post_var.year, month=post_var.month, podr=post_var.podr, profile=post_var.profile, dn_lg=post_var.dn_lg, dk_lg=post_var.dk_lg, dn_pl=post_var.dn_pl, dk_pl=post_var.dk_pl)
            result = Buhreport.objects.filter(year=post_var.year, month=post_var.month, podr=post_var.podr, profile=post_var.profile).first()
        return {"ok": True, "status": 200, "message": "Успешно сформирован отчет", "docs": result.list_docs, "techs": result.list_techs, "pols": result.list_pols, "lits": result.list_lits, "cadcams": result.list_cadcams, "zp_techs": result.list_zp_techs, "zp_pols": result.list_zp_pols, "zp_lits": result.list_zp_lits, "zp_cadcams": result.list_zp_cadcams, "file": result.file if result.file else ""}
    list_podr = [165, 3, 32, 245, 243, 236, 164, 162, 28]
    for podr in list_podr:
        if Buhreport.objects.filter(year=post_var.year, month=post_var.month, profile=post_var.profile, podr=podr).exists():
            continue
        print(post_var.profile)
        create_buh_report(year=post_var.year, month=post_var.month, podr=podr, profile=post_var.profile, dn_lg=post_var.dn_lg, dk_lg=post_var.dk_lg, dn_pl=post_var.dn_pl, dk_pl=post_var.dk_pl)
    result_all = Buhreport.objects.filter(year=post_var.year, month=post_var.month, profile=post_var.profile)
    list_docs = [res.list_docs for res in result_all]
    list_docs = unpack_doc(list_docs)
    list_techs = [res.list_techs for res in result_all]
    list_techs = unpack_spec(list_techs)
    list_pols = [res.list_pols for res in result_all]
    list_pols = unpack_spec(list_pols)
    list_lits = [res.list_lits for res in result_all]
    list_lits = unpack_spec(list_lits)
    list_cadcams = [res.list_cadcams for res in result_all]
    list_cadcams = unpack_spec(list_cadcams)
    list_zp_techs = [res.list_zp_techs for res in result_all]
    list_zp_techs = unpack_spec(list_zp_techs)
    list_zp_pols = [res.list_zp_pols for res in result_all]
    list_zp_pols = unpack_spec(list_zp_pols)
    list_zp_lits = [res.list_zp_lits for res in result_all]
    list_zp_lits = unpack_spec(list_zp_lits)
    list_zp_cadcams = [res.list_zp_cadcams for res in result_all]
    list_zp_cadcams = unpack_spec(list_zp_cadcams)
    Buhreport.objects.filter(year=post_var.year, month=post_var.month, profile=post_var.profile, podr=post_var.podr).delete()
    report = Buhreport.objects.create(
            year=post_var.year,
            month=post_var.month,
            profile=post_var.profile,
            podr=post_var.podr,
            )
    xlsx_gen.to_xls(
        report=report,
        dzr_start=post_var.dn_pl,
        dzr_end=post_var.dk_pl,
        dzr_lgot_start=post_var.dn_lg,
        dzr_lgot_end=post_var.dk_lg,
        list_docs=list_docs,
        list_techs=list_techs,
        list_pols=list_pols,
        list_lits=list_lits,
        list_cadcams=list_cadcams,
        list_zp_techs=list_zp_techs,
        list_zp_pols=list_zp_pols,
        list_zp_lits=list_zp_lits,
        list_zp_cadcams=list_zp_cadcams,
        )
    report.refresh_from_db()
    # file = ""
    return {"ok": True, "status": 200, "message": "Успешно сформирован отчет", "docs": list_docs, "techs": list_techs, "pols": list_pols, "lits": list_lits, "cadcams": list_cadcams, "zp_techs": list_zp_techs, "zp_pols": list_zp_pols, "zp_lits": list_zp_lits, "zp_cadcams": list_zp_cadcams, "file": report.file if report.file else ""}

def unpack_spec(data) -> list:
    result = []
    for x in data:
        if isinstance(x, list):
            for y in x:
                result.append(y)
        else:
            result.append(x)
    result_dict = {}
    for res in result:
        if res["mpp"] in result_dict:
            element_dict = result_dict.pop(res["mpp"])
            element_dict["lab_pd"] += res["lab_pd"]
            element_dict["lab_vt"] += res["lab_vt"]
            element_dict["lab_itog"] += res["lab_itog"]
            element_dict["lab_lgot"] += res["lab_lgot"]
            result_dict[res["mpp"]] = element_dict
        else:
            result_dict[res["mpp"]] = res
    # return result
    return list(result_dict.values())


def unpack_doc(data) -> list:
    result = []
    for x in data:
        if isinstance(x, list):
            for y in x:
                result.append(y)
        else:
            result.append(x)
    result_dict = {}
    for res in result:
        if res["mpp"] in result_dict:
            # print(res)
            # print(result_dict[res["mpp"]])
            element_dict = result_dict.pop(res["mpp"])
            element_dict["lab_pd"] += res["lab_pd"]
            element_dict["lab_vt"] += res["lab_vt"]
            element_dict["usl_pd"] += res["usl_pd"]
            element_dict["usl_vt"] += res["usl_vt"]
            element_dict["lab_itog"] += res["lab_itog"]
            element_dict["lab_lgot"] += res["lab_lgot"]
            element_dict["usl_itog"] += res["usl_itog"]
            element_dict["usl_lgot"] += res["usl_lgot"]
            result_dict[res["mpp"]] = element_dict
        else:
            result_dict[res["mpp"]] = res
    # return result
    return list(result_dict.values())

class PeriodsSchema(Schema):
    id: int
    years: int
    months: int
    nmonth: str
    dn_pl: date
    dk_pl: date
    dn_lg: date
    dk_lg: date
    disabled: bool = None


class SuccessNaryadInfoResponseSchema(Schema):
    ok: bool
    status: int
    data: NaryadSchema = None


@router.get("/naryad_info/", response=SuccessNaryadInfoResponseSchema)
def naryad_info(request, naryad: str):  # noqa: ANN201, ARG001
    if naryad != "" and len(naryad) > 0 and naryad[0] in ("a", "а", "А"):
        naryad = f"A{naryad[1:]}"
    nar = It_lab.objects.filter(nkv=naryad).first()
    if nar is None:
        return {"ok": False, "status": 203}
    return {"ok": True, "status": 200, "data": nar}


@router.get("/period_date_dj/", response=list[PeriodsSchema])
def period_date_dj(request) -> list[PeriodsSchema]:  # noqa: ARG001
    date_zero = {
        "id": 0,
        "nmonth": "Выбрать период",
        "dn_pl": "2022-05-26T00:00:00",
        "dk_pl": "2022-06-25T00:00:00",
        "dn_lg": "2022-05-21T00:00:00",
        "dk_lg": "2022-06-20T00:00:00",
        "years": 2022,
        "months": 6,
        "disabled": True,
    }
    return [date_zero, *Periods.objects.order_by("id").all()]

class ResponseNarForCheckSchema(Schema):
    nkv: str
    dou: date
    dzr: date
    patient: str
    naryad_doc__user__fam: str
    stu: Decimal
    lpu__name_lpu: str
    laboratory: bool


class ResponseNarForCheckAllSchema(StatusMessage):
    nars: list[ResponseNarForCheckSchema]

@router.get("/nar_for_check/")
def nar_for_check(request, mpp: int, spec: str, profile: int, podr: int, dn_lg, dk_lg, dn_pl, dk_pl):  # noqa: ANN201, ARG001, PLR0913
    print(mpp, spec, profile, podr, dn_lg, dk_lg, dn_pl, dk_pl)
    nars = It_lab.objects.filter(profile_otd=profile).filter((Q(dzr__range=(dn_pl, dk_pl)) & Q(opl__opl__gte=2)) | (Q(dzr__range=(dn_lg, dk_lg)) & Q(opl__opl=1)))
    if podr > 1:
        nars = nars.filter(lpu__lpu=podr)
    if spec == "doc":
        nars = nars.filter(sdl_set__doc=mpp)
    if spec == "tech":
        nars = nars.filter(sdl_set__tech=mpp)
    if spec == "pol":
        nars = nars.filter(sdl_set__pol=mpp)
    if spec == "lit":
        nars = nars.filter(sdl_set__lit=mpp)
    if spec == "cadcam":
        nars = nars.filter(sdl_set__cadcam=mpp)
    result = list(nars.annotate(patientf=Concat("patient__fam", Value(" "), "patient__im", Value(" "), "patient__ot", output_field=CharField())).values("nkv", "dou", "dzr", "patientf", "naryad_doc__user__fam", "stu", "lpu__name_lpu", "laboratory"))
    return {"ok": True, "status": 200, "message": "Успешно получен список специалистов", "nars": result}


@router.get("/test_auth_log/")
# @login_for_logs_by_mpp
def test_auth_log(request):  # noqa: ANN201, ARG001
    return {"ok": True, "status": 200, "message": "Успешно получен список специалистов"}


class NaryadOtrodontSchema(Schema):
    id: int
    patient_name: str
    patient__dr: date
    nkv: str
    dou: date
    stu: Decimal
    lpu__name_lpu: str
    opl__name_opl: str
    sdl_set__doc: int
    sdl_set__tech: int
    sdl_set__lit: int
    sdl_set__pol: int
    sdl_set__cadcam: int
    naryad_doc__user__fam: str
    naryad_doc__user__im: str
    naryad_doc__user__ot: str = None


@router.get("/nar_ortodont_open/", response={200:list[NaryadOtrodontSchema]})
# @login_for_logs_by_mpp
def nar_ortodont_open(request, podr: int):  # noqa: ANN201, ARG001
    if podr > 0:
        nars = It_lab.objects.filter(profile_otd=3, pdzr__isnull=True, dzr__isnull=True, lpu__lpu=podr).order_by("dou")
    else:
        nars = It_lab.objects.filter(profile_otd=3, pdzr__isnull=True, dzr__isnull=True).order_by("dou")
    logging.warning(len(nars))
    return nars.annotate(patient_name=Concat(F("patient__fam"), Value(" "), F("patient__im"), Value(" "), F("patient__ot"), output_field=CharField())).values("id", "nkv", "patient_name", "stu", "lpu__name_lpu", "patient_name", "opl__name_opl", "dou", "sdl_set__doc", "sdl_set__tech", "sdl_set__lit", "sdl_set__pol", "sdl_set__cadcam", "naryad_doc__user__fam", "naryad_doc__user__im",  "naryad_doc__user__ot", "patient__dr")


class XlsxGenShema(Schema):
    file: str


@router.post("/xlsx_gen_zp/")
def xlsx_gen_zp(request):
    xlsx_gen.to_xls()
